#include <memory.hh>
#include <cmath>
#include <fstream>
#include <iostream>

bool memory_load::parse_memory_file()
{
    if(time_stamp + std::chrono::microseconds(100) > std::chrono::steady_clock::now()) {
        return true;
    }
    std::ifstream memory_file;
    memory_file.open(this->memory_info_file);
    this->time_stamp = std::chrono::steady_clock::now();
    if(!memory_file.is_open()) {
        return false;
    }

    std::string line;
    while(std::getline(memory_file,line)) {
        sscanf(line.c_str(),"MemTotal:%lu",&this->total_memory_in_KB);
        sscanf(line.c_str(),"MemAvailable:%lu",&this->current_memory_avail_in_KB);
    }
    memory_file.close();
    return true;
}
uint64_t memory_load::get_total_memory_in_KB()
{
    this->parse_memory_file();
    
    return this->total_memory_in_KB;
}

uint64_t memory_load::get_current_memory_usage_in_KB()
{
    this->parse_memory_file();
    return this->get_total_memory_in_KB() - this->current_memory_avail_in_KB;
}
float memory_load::get_current_memory_usage_in_percent()
{
    this->parse_memory_file();
    uint64_t mem_usage = this->get_current_memory_usage_in_KB();
    return round((mem_usage*100.0 / this->get_total_memory_in_KB()));
}

 uint64_t memory_load::get_memory_used_by_process(int pid)
 {
    uint64_t MemFree = 0;
    std::ifstream memory_file;

    std::string process_file_name = this->memory_info_process_prefix_file + std::to_string(pid) + "/status";

    //printf("----process name :%s\n",process_file_name.c_str());
    memory_file.open(process_file_name);

    
    std::string line;
    while (std::getline(memory_file, line)) {
        sscanf(line.c_str(), "VmSize: %lu", &MemFree);
    }
    return MemFree;

 }
cJSON* memory_load::to_json()
{
    cJSON* cjson = cJSON_CreateObject();
    uint64_t total_size = get_total_memory_in_KB();
    cJSON_AddNumberToObject(cjson, "total_KB", total_size); 

    uint64_t usage = get_current_memory_usage_in_KB();
    cJSON_AddNumberToObject(cjson, "usage_KB", usage); 
    return cjson;
}
const char*  memory_load::get_name()
{
    return "memory_load";
}
memory_load::~memory_load(){

}